package com.ljk.util;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.lang.id.NanoId;
import com.ljk.util.date.DateUtil;

public class IdUtil {

    private static final long WORKER_ID_BITS = 5L;
    // 最大支持机器节点数0~31，一共32个
    @SuppressWarnings({"PointlessBitwiseExpression", "FieldCanBeLocal"})
    private static final long MAX_WORKER_ID = -1L ^ (-1L << WORKER_ID_BITS);
    private static final long DATA_CENTER_ID_BITS = 5L;
    // 最大支持数据中心节点数0~31，一共32个
    @SuppressWarnings({"PointlessBitwiseExpression", "FieldCanBeLocal"})
    private static final long MAX_DATA_CENTER_ID = -1L ^ (-1L << DATA_CENTER_ID_BITS);

    // ------------------------------------------------------------------- UUID

    /**
     * 获取随机UUID
     * 特点:更安全的随机码
     *
     * @return 随机UUID
     */
    public static String randomUUID() {
        return UUID.randomUUID().toString();
    }

    /**
     * 简化的UUID，去掉了横线
     * 特点:更安全的随机码
     *
     * @return 简化的UUID，去掉了横线
     */
    public static String simpleUUID() {
        return UUID.randomUUID().toString(true);
    }

    /**
     * 获取随机UUID，使用性能更好的ThreadLocalRandom生成UUID
     * 特点:更好的性能
     *
     * @return 随机UUID
     * @since 4.1.19
     */
    public static String fastUUID() {
        return UUID.fastUUID().toString();
    }

    /**
     * 简化的UUID，去掉了横线，使用性能更好的ThreadLocalRandom生成UUID
     * 特点:更好的性能
     *
     * @return 简化的UUID，去掉了横线
     * @since 4.1.19
     */
    public static String fastSimpleUUID() {
        return UUID.fastUUID().toString(true);
    }

    /**
     * 创建MongoDB ID生成策略实现<br>
     * ObjectId由以下几部分组成：
     *
     * <pre>
     * 1. Time 时间戳。
     * 2. Machine 所在主机的唯一标识符，一般是机器主机名的散列值。
     * 3. PID 进程ID。确保同一机器中不冲突
     * 4. INC 自增计数器。确保同一秒内产生objectId的唯一性。
     * </pre>
     * <p>
     * 参考：http://blog.csdn.net/qxc1281/article/details/54021882
     *
     * @return ObjectId
     */
    public static String objectId() {
        return cn.hutool.core.util.IdUtil.objectId();
    }

    // ------------------------------------------------------------------- NanoId

    /**
     * 获取随机NanoId
     *
     * @return 随机NanoId
     * @since 5.7.5
     */
    public static String nanoId() {
        return cn.hutool.core.util.IdUtil.nanoId();
    }

    /**
     * 获取随机NanoId
     *
     * @param size ID中的字符数量
     * @return 随机NanoId
     * @since 5.7.5
     */
    public static String nanoId(int size) {
        return NanoId.randomNanoId(size);
    }


    /**
     * 复用hutool的雪花算法,workerId和数据中心Id使用mac地址动态计算的
     * 雪花算法的范围为69年,我手动指定了起始日期,所以,结束时间延长了
     */
    private static final Snowflake snowflake = new Snowflake(DateUtil.of(2025, 1, 1),
            cn.hutool.core.util.IdUtil.getWorkerId(cn.hutool.core.util.IdUtil.getDataCenterId(MAX_DATA_CENTER_ID), MAX_WORKER_ID),
            cn.hutool.core.util.IdUtil.getDataCenterId(MAX_DATA_CENTER_ID), false);

    /**
     * 简单获取Snowflake 的 nextId
     * 终端ID 数据中心ID 默认为PID和MAC地址生成
     *
     * @return nextId
     * @since 5.7.18
     */
    public static long getSnowflakeNextId() {
        return snowflake.nextId();
    }

    /**
     * 简单获取Snowflake 的 nextId
     * 终端ID 数据中心ID 默认为PID和MAC地址生成
     *
     * @return nextIdStr
     * @since 5.7.18
     */
    public static String getSnowflakeNextIdStr() {
        return snowflake.nextIdStr();
    }

}
